home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 526-550 / disk_527 / toolmanager / source / ifficon.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  7KB  |  225 lines

  1. /*
  2.  * ifficon.c   V1.4
  3.  *
  4.  * IFF brush handling
  5.  *
  6.  * (c) 1991 by Stefan Becker
  7.  *
  8.  */
  9. #include "ToolManager.h"
  10.  
  11. /* Our own DiskObject definition */
  12. struct IFFDObj {
  13.                 struct DiskObject id_dobj;
  14.                 struct Image      id_img;
  15.                 ULONG             id_size; /* size of image */
  16.                };
  17.  
  18. /* Bitmap header (BMHD) structure */
  19. struct BitMapHeader {
  20.                      UWORD w,h;                   /* Width, height in pixels */
  21.                      WORD  x,y;
  22.                      UBYTE nplanes;               /* Number of planes */
  23.                      UBYTE Masking;               /* Masking */
  24.                      UBYTE Compression;           /* Compression algorithm */
  25.                      UBYTE pad1;
  26.                      UWORD TransparentColor;
  27.                      UBYTE XAspect,YAspect;
  28.                      WORD  PageWidth, PageHeight;
  29. };
  30. #define MSK_HASMASK   1
  31. #define COMP_NO       0
  32. #define COMP_BYTERUN1 1
  33. #define BPR(w)        ((((w)+15)>>4)<<1) /* Bytes per row formula */
  34.  
  35. /* IFF ID's */
  36. #define ID_ILBM MAKE_ID('I','L','B','M')
  37. #define ID_BMHD MAKE_ID('B','M','H','D')
  38. #define ID_BODY MAKE_ID('B','O','D','Y')
  39.  
  40. /* miscellaneous */
  41. struct Library *IFFParseBase;
  42.  
  43. /* Read BODY chunk into memory and convert it to an image */
  44. static BOOL ReadBODY(struct IFFHandle *iff, struct BitMapHeader *bmhd,
  45.                      UBYTE *dest, ULONG bpr, ULONG planeoff)
  46. {
  47.  register UBYTE *sp,*dp;
  48.  register ULONG row;
  49.  UBYTE *src;
  50.  ULONG planes=bmhd->nplanes;
  51.  ULONG size=CurrentChunk(iff)->cn_Size;
  52.  BOOL ncomp=bmhd->Compression==COMP_NO;
  53.  BOOL mask=bmhd->Masking==MSK_HASMASK;
  54.  BOOL rc=TRUE;
  55.  
  56.  /* Get memory for BODY chunk contents */
  57.  if (!(sp=src=malloc(size))) goto rbe1;
  58.  
  59.  /* Read in the complete BODY chunk */
  60.  if (ReadChunkBytes(iff,src,size)!=size) goto rbe2;
  61.  
  62.  for (row=0; row<bmhd->h; row++)        /* Read data row by row */
  63.   {
  64.    register ULONG pl,rem;
  65.    register char k;
  66.  
  67.    for (pl=0; pl<planes; pl++)          /* Read data plane by plane */
  68.     {
  69.      dp=dest+pl*planeoff+row*bpr;       /* Calculate destination pointer */
  70.  
  71.      if (ncomp)
  72.       for (k=bpr; k--;) *dp++=*sp++;    /* No compression */
  73.      else
  74.       {                                 /* Byte Run compression */
  75.        rem=bpr;
  76.  
  77.        while (rem)                      /* Row not completed */
  78.         {
  79.          k=*sp++;                       /* Read compression code */
  80.  
  81.          if (k>=0)
  82.           {                             /* Literal copy */
  83.            if ((rem-=++k)<0) goto rbe2; /* Error in de-compression? */
  84.  
  85.            while (k--) *dp++=*sp++;     /* Copy the following k+1 bytes */
  86.           }
  87.          else if (k!=-128)              /* Code -128 == No Operation */
  88.           {                             /* Byte run encoded */
  89.            register UBYTE byte;
  90.  
  91.            k=-k;
  92.            if ((rem-=++k)<0) goto rbe2; /* Error in de-compression? */
  93.  
  94.            byte=*sp++;                  /* Get byte */
  95.            while (k--) *dp++=byte;      /* Copy this byte -k+1 times */
  96.           }
  97.         }
  98.       }
  99.     }
  100.  
  101.    if (mask)                            /* Skip mask plane */
  102.     if (ncomp)
  103.      sp+=bpr;                           /* No compression */
  104.     else
  105.      {                                  /* Byte Run compression */
  106.       rem=bpr;
  107.  
  108.       while (rem)                       /* Row not completed */
  109.        {
  110.         k=*sp++;                        /* Read compression code */
  111.  
  112.         if (k>=0)
  113.          {                              /* Literal copy */
  114.           if ((rem-=++k)<0) goto rbe2;  /* Error in de-compression? */
  115.           sp+=k;                        /* Skip the following k+1 bytes */
  116.          }
  117.         else if (k!=-128)               /* Code -128 == No Operation */
  118.          {                              /* Byte run encoded */
  119.           k=-k;
  120.           if ((rem-=++k)<0) goto rbe2;  /* Error in de-compression? */
  121.           sp++;                         /* Skip this byte */
  122.          }
  123.        }
  124.      }
  125.   }
  126.  
  127.  /* All OK */
  128.  rc=FALSE;
  129.  
  130. rbe2: free(src);
  131. rbe1: return(rc);
  132. }
  133.  
  134. /* Load an IFF brush and create a DiskObject */
  135. struct DiskObject *LoadIFFIcon(char *name)
  136. {
  137.  register struct IFFHandle *iff;
  138.  register struct IFFDObj *id=NULL;
  139.  struct ContextNode *cn;
  140.  struct StoredProperty *sp;
  141.  struct BitMapHeader *bmhd;
  142.  ULONG bpr,planeoff;
  143.  BOOL error=TRUE;
  144.  
  145.  /* Open IFF parsing library */
  146.  if (!(IFFParseBase=OpenLibrary("iffparse.library",0))) goto lie1;
  147.  
  148.  /* Get memory for DiskObject and clear it */
  149.  if (!(id=calloc(sizeof(struct IFFDObj),1))) goto lie2;
  150.  id->id_dobj.do_Version=WB_DISKVERSION;
  151.  id->id_dobj.do_Gadget.GadgetRender=&id->id_img;
  152.  id->id_dobj.do_Gadget.UserData=(APTR) WB_DISKREVISION;
  153.  
  154.  /* Alloc IFF handle */
  155.  if (!(iff=AllocIFF())) goto lie3;
  156.  
  157.  /* Open IFF file and init IFF handle */
  158.  if (!(iff->iff_Stream=Open(name,MODE_OLDFILE))) goto lie4;
  159.  InitIFFasDOS(iff);
  160.  
  161.  /* Declare ILBM property & stop chunks. Open IFF context */
  162.  if (PropChunk(iff,ID_ILBM,ID_BMHD)) goto lie5;
  163.  if (StopChunk(iff,ID_ILBM,ID_BODY)) goto lie5;
  164.  if (StopOnExit(iff,ID_ILBM,ID_FORM)) goto lie5;
  165.  if (OpenIFF(iff,IFFF_READ)) goto lie5;
  166.  
  167.  /* Start parsing */
  168.  if (ParseIFF(iff,IFFPARSE_STEP)) goto lie6;
  169.  
  170.  /* Check for FORM ILBM chunk */
  171.  if (!(cn=CurrentChunk(iff))) goto lie6;
  172.  if ((cn->cn_ID!=ID_FORM) || (cn->cn_Type!=ID_ILBM)) goto lie6;
  173.  
  174.  /* Continue parsing until BODY chunk is found */
  175.  if (ParseIFF(iff,IFFPARSE_SCAN)) goto lie6;
  176.  
  177.  /* BMHD chunk found? */
  178.  if (!(sp=FindProp(iff,ID_ILBM,ID_BMHD))) goto lie6;
  179.  bmhd=(struct BitMapHeader *) sp->sp_Data;
  180.  
  181.  /* Check compression type */
  182.  if ((bmhd->Compression!=COMP_NO) && (bmhd->Compression!=COMP_BYTERUN1))
  183.   goto lie6;
  184.  
  185.  /* Retrieve BMHD chunk values */
  186.  id->id_dobj.do_Gadget.Width=bmhd->w;
  187.  id->id_dobj.do_Gadget.Height=bmhd->h+1;
  188.  id->id_img.Width=bmhd->w;
  189.  id->id_img.Height=bmhd->h;
  190.  id->id_img.Depth=bmhd->nplanes;
  191.  id->id_img.PlanePick=(1<<bmhd->nplanes)-1;
  192.  
  193.  /* Allocate chip memory for image data */
  194.  bpr=BPR(bmhd->w);                   /* Bytes per row */
  195.  planeoff=bpr*bmhd->h;               /* Bytes per plane */
  196.  id->id_size=planeoff*bmhd->nplanes; /* Bytes for image */
  197.  if (!(id->id_img.ImageData=AllocMem(id->id_size,
  198.                                      MEMF_PUBLIC|MEMF_CHIP|MEMF_CLEAR)))
  199.   goto lie6;
  200.  
  201.  /* Read ImageData */
  202.  error=ReadBODY(iff,bmhd,(UBYTE *) id->id_img.ImageData,bpr,planeoff);
  203.  
  204.       if (error) FreeMem(id->id_img.ImageData,id->id_size);
  205. lie6: CloseIFF(iff);
  206. lie5: Close(iff->iff_Stream);
  207. lie4: FreeIFF(iff);
  208. lie3: if (error)
  209.        {
  210.         free(id);
  211.         id=NULL;
  212.        }
  213. lie2: CloseLibrary(IFFParseBase);
  214. lie1: return(id);
  215. }
  216.  
  217. /* Free an IFF icon */
  218. void FreeIFFIcon(struct DiskObject *dobj)
  219. {
  220.  register struct IFFDObj *id=dobj;
  221.  
  222.  FreeMem(id->id_img.ImageData,id->id_size);
  223.  free(id);
  224. }
  225.